package com.xnx3.j2ee.util;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import com.xnx3.BaseVO;
import com.xnx3.j2ee.Global;
import com.xnx3.j2ee.util.AttachmentMode.bean.SubFileBean;
import com.xnx3.j2ee.vo.UploadFileVO;
import com.xnx3.net.OSSUtil;
import com.xnx3.net.ossbean.PutResult;
import cn.zvo.fileupload.StorageInterface;
import cn.zvo.fileupload.framework.springboot.ApplicationConfig;
import cn.zvo.fileupload.framework.springboot.FileUpload;
import cn.zvo.fileupload.framework.springboot.FileUploadUtil;
import cn.zvo.fileupload.storage.local.LocalStorage;

/**
 * 文件上传，附件的操作，如云存储、或服务器本地文件
 * 如果是localFile ，则需要设置 AttachmentFile.netUrl。 
 * @author 管雷鸣
 */
@Component
public class AttachmentUtil {
	/**
	 * @deprecated
	 */
	private static String maxFileSize;								//application.properties 中配置的，比如3MB
	/**
	 * @deprecated
	 */
	private static int maxFileSizeKB = -1;							//最大上传限制，单位：KB，在getMaxFileSizeKB()获取
	
	/**
	 * @deprecated
	 */
	public static String mode;										//当前文件附件存储使用的模式，用的阿里云oss，还是服务器本身磁盘进行存储
	
	/**
	 * @deprecated
	 */
	public static final String MODE_ALIYUN_OSS = "aliyunOSS";		//阿里云OSS模式存储
	
	/**
	 * @deprecated
	 */
	public static final String MODE_LOCAL_FILE = "localFile";		//服务器本身磁盘进行附件存储
	
	/**
	 * @deprecated
	 */
	public static final String MODE_HUAWEIYUN_OBS = "huaWeiYunOBS";	//华为云OBS模式存储
	
	/**
	 * @deprecated
	 */
	public static final String MODE_KUOZHAN = "kuozhan";			//自己扩展的存储方式，比如存到百度云、七牛云等。
	
	/**
	 * @deprecated
	 */
	public static StorageInterface storageMode;					//会根据数据库中 mode 的值，决定创建什么模式的存储。不可直接使用，需使用 getStorageMode() 获取
	
	/**
	 * @deprecated
	 */
	//文件路径，文件所在。oss则为OSSUtil.url， localFile则是存储到磁盘，访问时自然就是主域名
	public static String netUrl = null;
	
	/**
	 * @deprecated
	 */
	//如果附件保存在当前服务器上，则保存的路径是哪个
	public static String localFilePath = "";	
	
	/**
	 * @deprecated
	 */
	/**
	 * 是否是手动设置了 StorageModeInterface接口，是，则是true，默认是false。
	 */
	private static boolean isSetStorageMode = false;
	
	/**
	 * @deprecated
	 */
	/**
	 * 使用时，你不需要 new AttachmentUtil() ，你直接使用 AttachmentUtil. 即可！这个是交给tomcat启动后自动执行初始化用的
	 */
	public AttachmentUtil() {
		
		new Thread(new Runnable() {
			@Override
			public void run() {
				while(Global.system.size() < 1){
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
				//当 system数据表 加载后才会执行
				
				String mode = SystemUtil.get("ATTACHMENT_FILE_MODE");
				if(mode == null || mode.length() < 1) {
					return;
				}
				
				if(mode.equalsIgnoreCase(MODE_HUAWEIYUN_OBS)) {
					//使用华为云obs
					ConsoleUtil.info("HuaweiyunOBSMode init start...");
					
					Map<String, Map<String, String>> storage = new HashMap<String, Map<String,String>>();
					Map<String, String> obs = new HashMap<String, String>();
					obs.put("accessKeyId", SystemUtil.get("HUAWEIYUN_ACCESSKEYID"));
					obs.put("accessKeySecret", SystemUtil.get("HUAWEIYUN_ACCESSKEYSECRET"));
					obs.put("endpoint", SystemUtil.get("HUAWEIYUN_OBS_ENDPOINT"));
					obs.put("obsname", SystemUtil.get("HUAWEIYUN_OBS_BUCKETNAME"));
					storage.put("huaweicloudOBS", obs);
					
					ApplicationConfig config = new ApplicationConfig();
					config.setStorage(storage);
					config.setDomain(SystemUtil.get("ATTACHMENT_FILE_URL"));
					FileUploadUtil.loadConfig(config);
					ConsoleUtil.debug("FileUpload 使用华为云OBS存储");
				}else if(mode.equalsIgnoreCase(MODE_ALIYUN_OSS)) {
					//阿里云oss
					ConsoleUtil.info("AliyunOSSMode init start...");
					
					String accessKeyId = SystemUtil.get("ALIYUN_ACCESSKEYID");
					String accessKeySecret = SystemUtil.get("ALIYUN_ACCESSKEYSECRET");
					String bucketName = SystemUtil.get("ALIYUN_OSS_BUCKETNAME");
					String endpoint = SystemUtil.get("ALIYUN_OSS_ENDPOINT");
					
//					if(OSSUtil.accessKeyId == null || OSSUtil.accessKeySecret.length() < 10){
//						ConsoleUtil.info("OSS对象存储初始化时，accessKeyId 或 accessKeyId 无有效值（字符小于10）");
//						return;
//					}
					
					Map<String, Map<String, String>> storage = new HashMap<String, Map<String,String>>();
					Map<String, String> oss = new HashMap<String, String>();
					oss.put("accessKeyId", SystemUtil.get("ALIYUN_ACCESSKEYID"));
					oss.put("secretAccessKey", SystemUtil.get("ALIYUN_ACCESSKEYSECRET"));
					oss.put("endpoint", SystemUtil.get("ALIYUN_OSS_ENDPOINT"));
					oss.put("bucketname", SystemUtil.get("ALIYUN_OSS_BUCKETNAME"));
					storage.put("aliyunOSS", oss);
					
					ApplicationConfig config = new ApplicationConfig();
					config.setStorage(storage);
					config.setDomain(SystemUtil.get("ATTACHMENT_FILE_URL"));
					FileUploadUtil.loadConfig(config);
					ConsoleUtil.debug("FileUpload 使用aliyun oss存储  -- 未经过测试，还需测试是否正常支持");
				}else if(mode.equalsIgnoreCase(MODE_LOCAL_FILE)) {
					//本地存储方式 ，那么直接忽略，因为 FileUpload 默认就是本地存储，同时也是避免吧application.properties中的配置给冲掉
//					
//					Map<String, Map<String, String>> storage = new HashMap<String, Map<String,String>>();
//					Map<String, String> map = new HashMap<String, String>();
////					oss.put("path", "...放啥呢");
//					storage.put("local", map);
//					
					if(SystemUtil.get("ATTACHMENT_FILE_URL") != null && SystemUtil.get("ATTACHMENT_FILE_URL").length() > 3) {
						ApplicationConfig config = new ApplicationConfig();
						config.setDomain(SystemUtil.get("ATTACHMENT_FILE_URL"));
						FileUploadUtil.loadConfig(config);
						ConsoleUtil.debug("FileUpload 设置 system 表的 ATTACHMENT_FILE_URL ："+SystemUtil.get("ATTACHMENT_FILE_URL"));
						ConsoleUtil.debug("\t如果手动将system表的ATTACHMENT_FILE_URL的value设置为空，那么就不在使用system表的ATTACHMENT_FILE_URL，而是使用application.properties 配置文件中的 fileupload.domain 设置。建议使用配置文件的方式");
					}
					
				}
				
				if(mode.equalsIgnoreCase(MODE_HUAWEIYUN_OBS) || mode.equalsIgnoreCase(MODE_ALIYUN_OSS) || mode.equalsIgnoreCase(MODE_LOCAL_FILE)){
					System.out.println("=== 提醒，后续再新项目中配置文件上传时，请在application.properties中配置。详细参见：  ===");
					System.out.println("参见 https://github.com/xnx3/FileUpload");
					System.out.println("===========");
				}
				
			}
		}).start();
		
		localFilePath = SystemUtil.getProjectPath();
	}
	
	
	/**
	 * 设置当前使用的存储模式。如果设置了此处，那么数据库中 ATTACHMENT_FILE_MODE 字段设置的存储方式将会失效，不会起任何作用。以此接口的设置为准
	 * @param storageMode 实现 {@link StorageInterface}接口
	 */
	public static void setStorageMode(StorageInterface storageMode) {
		FileUploadUtil.fileupload.setStorage(storageMode);
		isSetStorageMode = true;
		mode = AttachmentUtil.MODE_KUOZHAN;
		ConsoleUtil.debug("set attachment storage : " + storageMode.getClass().getSimpleName());
	}


	/**
	 * 获取当前使用的存储模式，进行存储。
	 * @return 如果在数据库表 system 表加载成功之前调用此方法，会返回null，当然，这个空指针几乎可忽略。实际使用中不会有这种情况
	 */
	public static StorageInterface getStorageMode(){
		return FileUploadUtil.fileupload.getStorage();
	}
	
	/**
	 * 获取当前允许上传的文件的最大大小
	 * @return 如 3MB 、 400KB 等
	 */
	public static String getMaxFileSize(){
		return FileUploadUtil.fileupload.getMaxFileSize();
	}
	
	/**
	 * 获取当前限制的上传文件最大的大小限制。单位是KB
	 * @return 单位KB
	 */
	public static int getMaxFileSizeKB(){
		return (int) FileUploadUtil.fileupload.getMaxFileSizeKB();
	}
	
	/**
	 * 判断当前文件附件存储使用的是哪种模式，存储到什么位置
	 * @param mode 存储的代码，可直接传入如 {@link #MODE_ALIYUN_OSS}
	 * @return 是否使用
	 * 			<ul>
	 * 				<li>true ： 是此种模式</li>
	 * 				<li>false ： 不是此种模式</li>
	 * 			</ul>
	 */
	public static boolean isMode(String mode){
		return FileUploadUtil.fileupload.isStorage(mode);
	}
	
	
	/**
	 * 获取附件访问的url地址
	 * @return 返回如 http://res.weiunity.com/   若找不到，则返回null
	 */
	public static String netUrl(){
		/*
		 * 
		 * 
		 * 
		 * 
		 */
//		if(netUrl == null){
//			netUrl = SystemUtil.get("ATTACHMENT_FILE_URL");
//			FileUploadUtil.fileupload.setDomain(netUrl);
//		}
//		return netUrl;
		
		if(FileUploadUtil.fileupload == null) {
			ConsoleUtil.error("异常，文件存储组件 FileUploadUtil.fileupload 为 null，应该是安装或配置有误导致的，可到相关仓库中提issues");
			return "";
		}
		String domain = FileUploadUtil.fileupload.getDomain();
		if(domain == null) {
			domain = "/";
			FileUploadUtil.fileupload.setDomain("/");
			ConsoleUtil.error("异常，文件存储组件 FileUploadUtil.fileupload.getDomain(); 为 null，应该是安装或配置有误导致的，已自动赋予 /");
		}
		return domain;
	}
	
	/**
	 * 设置当前的netUrl
	 * @param url 当前正在使用的附件url前缀，传入如： http://xxxx.com/
	 */
	public static void setNetUrl(String url){
		FileUploadUtil.fileupload.setDomain(url);
	}
	
	/**
	 * 给出文本内容，写出文件
	 * @param filePath 写出的路径,上传后的文件所在的目录＋文件名，如 "jar/file/xnx3.html"
	 * @param text 文本内容
	 * @param encode 编码格式，可传入 {@link FileUpload#GBK}、{@link FileUpload#UTF8}
	 */
	public static void uploadStringFile(String filePath, String text, String encode){
		FileUploadUtil.fileupload.uploadString(filePath, text, encode);
	}
	
	/**
	 * 给出文本内容，写出文件。写出UTF－8编码
	 * @param filePath 写出的路径,上传后的文件所在的目录＋文件名，如 "jar/file/xnx3.html"
	 * @param text 文本内容
	 */
	public static void uploadStringFile(String filePath, String text){
		FileUploadUtil.fileupload.uploadString(filePath, text, FileUpload.UTF8);
	}
	
	/**
	 * 给出文本内容，写出文件。写出UTF－8编码
	 * <p>已废弃，请使用 uploadStringFile </p>
	 * @param path 写出的路径,上传后的文件所在的目录＋文件名，如 "jar/file/xnx3.html"
	 * @param text 文本内容
	 * @deprecated
	 */
	public static void putStringFile(String path, String text){
		uploadStringFile(path, text, FileUpload.UTF8);
	}
	
	/**
	 * 给出文本内容，写出文件。写出UTF－8编码
	 * <p>已废弃，请使用 uploadStringFile </p>
	 * @param filePath 写出的路径,上传后的文件所在的目录＋文件名，如 "jar/file/xnx3.html"
	 * @param text 文本内容
	 * @param encode 编码格式，可传入 {@link FileUpload#GBK}、{@link FileUpload#UTF8}
	 * @deprecated 
	 */
	public static void putStringFile(String filePath, String text, String encode){
		uploadStringFile(filePath, text, encode);
	}
	
	/**
	 * 判断要上传的文件是否超出大小限制，若超出大小限制，返回出错原因
	 * @param file 要上传的文件，判断其大小是否超过系统指定的最大限制
	 * @return 若超出大小，则返回result:Failure ，info为出错原因
	 */
	public static UploadFileVO verifyFileMaxLength(File file){
		BaseVO vo = FileUploadUtil.fileupload.verifyFileMaxLength(file);
		UploadFileVO uploadFileVO = new UploadFileVO();
		uploadFileVO.setResult(vo.getResult());
		uploadFileVO.setInfo(vo.getInfo());
		return uploadFileVO;
	}
	
	/**
	 * 判断要上传的文件是否超出大小限制，若超出大小限制，返回出错原因
	 * @param lengthKB 要上传的文件的大小，判断其大小是否超过系统指定的最大限制，单位是KB
	 * @return 若超出大小，则返回result:Failure ，info为出错原因
	 */
	public static UploadFileVO verifyFileMaxLength(int lengthKB){
		BaseVO vo = FileUploadUtil.fileupload.verifyFileMaxLength(lengthKB);
		UploadFileVO uploadFileVO = new UploadFileVO();
		uploadFileVO.setResult(vo.getResult());
		uploadFileVO.setInfo(vo.getInfo());
		return uploadFileVO;
	}
	
	/**
	 * 上传本地文件
	 * @param filePath 上传后的文件所在的目录、路径，如 "jar/file/"
	 * @param localPath 本地要上传的文件的绝对路径，如 "/jar_file/iw.jar"
	 * @return {@link PutResult} 若失败，返回null
	 */
	public static UploadFileVO uploadFile(String filePath, String localPath){
		return uploadFileVOTransfer(FileUploadUtil.fileupload.upload(filePath, localPath));
	}
	
	/**
	 * 上传本地文件
	 * <p>已废弃，请使用 uploadFile </p>
	 * @param filePath 上传后的文件所在的目录、路径，如 "jar/file/"
	 * @param localPath 本地要上传的文件的绝对路径，如 "/jar_file/iw.jar"
	 * @return {@link PutResult} 若失败，返回null
	 * @deprecated
	 */
	public static UploadFileVO put(String filePath, String localPath){
		return uploadFile(filePath, localPath);
	}
	

	/**
	 * 上传本地文件。上传的文件名会被自动重命名为uuid+后缀
	 * @param filePath 上传后的文件所在的目录、路径，如 "jar/file/"
	 * @param localFile 本地要上传的文件
	 * @return {@link PutResult} 若失败，返回null
	 */
	public static UploadFileVO uploadFile(String filePath, File localFile){
		return uploadFileVOTransfer(FileUploadUtil.fileupload.upload(filePath, localFile));
	}
	
	/**
	 * 上传本地文件。上传的文件名会被自动重命名为uuid+后缀
	 * <p>已废弃，请使用 uploadFile </p>
	 * @param filePath 上传后的文件所在的目录、路径，如 "jar/file/"
	 * @param localFile 本地要上传的文件
	 * @return {@link PutResult} 若失败，返回null
	 * @deprecated
	 */
	public static UploadFileVO put(String filePath, File localFile){
		return uploadFile(filePath, localFile);
	}
	
	/**
	 * 上传文件。上传后的文件名固定
	 * <p>已废弃，请使用 uploadFile </p>
	 * @param path 上传到哪里，包含上传后的文件名，如"image/head/123.jpg"
	 * @param inputStream 文件
	 * @return {@link UploadFileVO}
	 * @deprecated
	 */
	public static UploadFileVO put(String path,InputStream inputStream){
		return uploadFile(path, inputStream);
	}
	
	/**
	 * 上传文件。上传后的文件名固定
	 * @param path 上传到哪里，包含上传后的文件名，如"image/head/123.jpg" 
	 * 			<p>注意，这里是跟着上传的文件名的，文件名叫什么，就保存成什么</p>
	 * @param inputStream 文件
	 * @return {@link UploadFileVO}
	 */
	public static UploadFileVO uploadFile(String path,InputStream inputStream){
		return uploadFileVOTransfer(FileUploadUtil.fileupload.upload(path, inputStream));
	}
	

	/**
	 * 上传图片，将网上的图片复制到自己这里。（如果网上图片的URL获取不到后缀，默认用 jpg）
	 * @param filePath 上传后的文件所在的目录、路径。 传入格式如： file/images/  会自动给上传的图片重命名保存
	 * @param imageUrl 网上图片的地址
	 * @return {@link UploadFileVO}
	 */
	public static UploadFileVO uploadImageByUrl(String filePath, String imageUrl){
		return uploadFileVOTransfer(FileUploadUtil.fileupload.uploadImage(filePath, imageUrl));
	}
	
	/**
	 * 上传图片，将网上的图片复制到自己这里。（如果网上图片的URL获取不到后缀，默认用 jpg）
	 * <p>已废弃，请使用 uploadImageByUrl </p>
	 * @param filePath 上传后的文件所在的目录、路径。 传入格式如： file/images/  会自动给上传的图片重命名保存
	 * @param imageUrl 网上图片的地址
	 * @return {@link UploadFileVO}
	 * @deprecated
	 */
	public static UploadFileVO putImageByUrl(String filePath, String imageUrl){
		return uploadImageByUrl(filePath, imageUrl);
	}
	
	
	/**
	 * 传入一个路径，得到其源代码(文本)
	 * @param path 要获取的文本内容的路径，如  site/123/index.html
	 * @return 返回其文本内容。若找不到，或出错，则返回 null
	 */
	public static String getTextByPath(String path){
		return FileUploadUtil.fileupload.getText(path);
	}
	
	/**
	 * 删除文件
	 * @param filePath 文件所在的路径，如 "jar/file/xnx3.jpg"
	 */
	public static void deleteObject(String filePath){
		FileUploadUtil.fileupload.delete(filePath);
	}
	
	/**
	 * 复制文件
	 * @param originalFilePath 原本文件所在的路径(相对路径，非绝对路径，操作的是当前附件文件目录下)
	 * @param newFilePath 复制的文件所在的路径，所放的路径。(相对路径，非绝对路径，操作的是当前附件文件目录下)
	 */
	public static void copyObject(String originalFilePath, String newFilePath){
		FileUploadUtil.fileupload.copy(originalFilePath, newFilePath);
	}
//	
//	/**
//	 * 上传文件。UEditor使用
//	 * @param filePath 上传到哪里，包含上传后的文件名，如"image/head/123.jpg"
//	 * @param input 文件流
//	 * @param meta {@link com.aliyun.oss.model.ObjectMetadata}其他属性、说明
//	 */
//	public static void putForUEditor(String filePath, InputStream input, ObjectMetadata meta){
//		//getStorageMode().putForUEditor(filePath, input, meta);	//v5.3注释掉， storageMede接口取消掉这个实现
//		put(filePath, input);
//	}
	

	/**
	 * SpringMVC 上传文件，配置允许上传的文件后缀再 systemConfig.xml 的attachmentFile.allowUploadSuffix.suffix节点
	 * @param filePath 上传后的文件所在目录、路径，如 "jar/file/"
	 * @param multipartFile SpringMVC接收的 {@link MultipartFile},若是有上传文件，会自动转化为{@link MultipartFile}保存
	 * @return {@link UploadFileVO} 若成功，则上传了文件并且上传成功
	 */
	public static UploadFileVO uploadFile(String filePath, MultipartFile multipartFile) {
		return uploadFileVOTransfer(FileUploadUtil.fileupload.upload(filePath, multipartFile));
	}
	
	
	/**
	 * SpringMVC 上传文件，配置允许上传的文件后缀再 systemConfig.xml 的attachmentFile.allowUploadSuffix.suffix节点
	 * <p>已废弃，请使用 uploadFile </p>
	 * @param filePath 上传后的文件所在目录、路径，如 "jar/file/"
	 * @param multipartFile SpringMVC接收的 {@link MultipartFile},若是有上传文件，会自动转化为{@link MultipartFile}保存
	 * @return {@link UploadFileVO} 若成功，则上传了文件并且上传成功
	 * @deprecated
	 */
	public static UploadFileVO uploadFileByMultipartFile(String filePath, MultipartFile multipartFile) {
		return uploadFile(filePath, multipartFile);
	}
	
	
	/**
	 * SpringMVC 上传图片文件，配置允许上传的文件后缀再 systemConfig.xml 的attachmentFile.allowUploadSuffix.suffix节点
	 * @param filePath 上传后的文件所在目录、路径，如 "jar/file/"
	 * @param multipartFile SpringMVC接收的 {@link MultipartFile},若是有上传图片文件，会自动转化为{@link MultipartFile}保存
	 * @param maxWidth 上传图片的最大宽度，若超过这个宽度，会对图片进行等比缩放为当前宽度。若传入0.则不启用此功能
	 * @return {@link UploadFileVO} 若成功，则上传了文件并且上传成功
	 */
	public static UploadFileVO uploadImageByMultipartFile(String filePath, MultipartFile multipartFile, int maxWidth) {
		return uploadFileVOTransfer(FileUploadUtil.fileupload.uploadImage(filePath, multipartFile, maxWidth));
	}
	
	/**
	 * SpringMVC 上传图片文件，配置允许上传的文件后缀再 systemConfig.xml 的attachmentFile.allowUploadSuffix.suffix节点
	 * @param filePath 上传后的文件所在目录、路径，如 "jar/file/"
	 * @param multipartFile SpringMVC接收的 {@link MultipartFile},若是有上传图片文件，会自动转化为{@link MultipartFile}保存
	 * @return {@link UploadFileVO} 若成功，则上传了文件并且上传成功
	 */
	public static UploadFileVO uploadImageByMultipartFile(String filePath, MultipartFile multipartFile) {
		return uploadImageByMultipartFile(filePath, multipartFile, 0);
	}
	
	/**
	 * 上传文件
	 * @param filePath 上传后的文件所在的目录、路径，如 "jar/file/"
	 * @param inputStream 要上传的文件的数据流
	 * @param fileSuffix 上传的文件的后缀名
	 * @return {@link UploadFileVO}
	 */
	public static UploadFileVO uploadFileByInputStream(String filePath, InputStream inputStream, String fileSuffix) {
		return uploadFileVOTransfer(FileUploadUtil.fileupload.upload(filePath, inputStream, fileSuffix));
	}
	
	/**
	 * 上传图片文件
	 * @param filePath 上传后的文件所在的目录、路径，如 "jar/file/"
	 * @param inputStream 图片的数据流
	 * @param fileSuffix 图片的后缀名
	 * @param maxWidth 上传图片的最大宽度，若超过这个宽度，会对图片进行等比缩放为当前宽度
	 * @return {@link UploadFileVO}
	 */
	public static UploadFileVO uploadImageByInputStream(String filePath, InputStream inputStream, String fileSuffix, int maxWidth) {
		return uploadFileVOTransfer(FileUploadUtil.fileupload.uploadImage(filePath, inputStream, fileSuffix, maxWidth));
	}
	
	
	//允许上传的后缀名数组，存储如 jpg 、 gif、zip
	public static String[] allowUploadSuffixs;
	
	/**
	 * 判断当前后缀名是否在可允许上传的后缀中
	 * @param fileSuffix 要判断的上传的文件的后缀名
	 * @return true：可上传，允许上传，后缀在指定的后缀列表中
	 * @deprecated
	 */
	public static boolean allowUploadSuffix(String fileSuffix){
		return FileUploadUtil.fileupload.isAllowUpload(fileSuffix);
	}
	
	
	/**
	 * 上传文件
	 * @param filePath 上传后的文件所在的目录、路径，如 "jar/file/"
	 * @param fileName 上传的文件名，如“xnx3.jar”；主要拿里面的后缀名。也可以直接传入文件的后缀名如“.jar。新的文件名会是自动生成的 uuid+后缀”
	 * @param inputStream {@link InputStream}
	 * @return {@link PutResult} 若失败，返回null
	 */
	public static UploadFileVO put(String filePath,String fileName,InputStream inputStream){
		return uploadFileVOTransfer(FileUploadUtil.fileupload.upload(filePath, fileName, inputStream));
	}

	
	/**
	 * SpringMVC 上传图片文件，配置允许上传的文件后缀再 systemConfig.xml 的AttachmentFile节点
	 * @param filePath 上传后的文件所在的目录、路径，如 "jar/file/"
	 * @param request SpringMVC接收的 {@link MultipartFile},若是有上传图片文件，会自动转化为{@link MultipartFile}保存
	 * @param formFileName form表单上传的单个图片文件，表单里上传文件的文件名
	 * @param maxWidth 上传图片的最大宽度，若超过这个宽度，会对图片进行等比缩放为当前宽度。
	 * @return {@link UploadFileVO} 若成功，则上传了文件并且上传成功
	 */
	public static UploadFileVO uploadImage(String filePath,HttpServletRequest request,String formFileName, int maxWidth) {
		return uploadFileVOTransfer(FileUploadUtil.fileupload.uploadImage(filePath, request, formFileName, maxWidth));
	}
	
	/**
	 * SpringMVC 上传文件，配置允许上传的文件后缀再 systemConfig.xml 的AttachmentFile节点
	 * @param filePath 上传后的文件所在的目录、路径，如 "jar/file/"
	 * @param request SpringMVC接收的 {@link MultipartFile},若是有上传文件，会自动转化为{@link MultipartFile}保存
	 * @param formFileName form表单上传的单个文件，表单里上传文件的文件名
	 * @return {@link UploadFileVO} 若成功，则上传了文件并且上传成功
	 */
	public static UploadFileVO uploadFile(String filePath,HttpServletRequest request,String formFileName) {
		return uploadFileVOTransfer(FileUploadUtil.fileupload.upload(filePath, request, formFileName));
	}
	
	/**
	 * 获取某个目录（文件夹）占用空间的大小
	 * @param path 要计算的目录(文件夹)，如 jar/file/
	 * @return 计算出来的大小。单位：字节，B。  千分之一KB
	 */
	public static long getDirectorySize(String path){
		return FileUploadUtil.fileupload.getDirectorySize(path);
	}
	
	/**
	 * 已废弃
	 * <p>目录检测，检测是否存在。若不存在，则自动创建目录。适用于使用本地磁盘进行存储</p>
	 * @param path 要检测的目录，相对路径，如 jar/file/  创建到file文件，末尾一定加/     或者jar/file/a.jar创建懂啊file文件
	 * @deprecated
	 */
	public static void directoryInit(String path){
		LocalStorage localStorage = new LocalStorage();
		localStorage.directoryInit(path);
	}
	
	/**
	 * 获取某个目录下的子文件列表。获取的只是目录下第一级的子文件，并非是在这个目录下无论目录深度是多少都列出来
	 * @param path 要获取的是哪个目录的子文件。传入如 site/219/
	 * @return 该目录下一级子文件（如果有文件夹，也包含文件夹）列表。如果size为0，则是没有子文件或文件夹。无论什么情况不会反null
	 */
	public static List<SubFileBean> getSubFileList(String path){
		List<cn.zvo.fileupload.bean.SubFileBean> resultList = FileUploadUtil.fileupload.getSubFileList(path);
		List<SubFileBean> list = new ArrayList<SubFileBean>();
		
		for (int i = 0; i < resultList.size(); i++) {
			cn.zvo.fileupload.bean.SubFileBean zvoBean = resultList.get(i);
			
			SubFileBean bean = new SubFileBean();
			BeanUtils.copyProperties(zvoBean, bean);
			list.add(bean);
		}
		return list;		
	}

	/**
	 * 获取某个文件的大小，这个是文件，如果传入文件夹，是不起作用的，会返回-1，文件未发现
	 * @param path 要获取的是哪个文件。传入如 site/219/1.html
	 * @return 单位是 B， * 1000 = KB 。 如果返回-1，则是文件未发现，文件不存在
	 */
	public static long getFileSize(String path){
		return FileUploadUtil.fileupload.getFileSize(path);
	}
	
	/**
	 * 创建文件夹
	 * @param path 要创建的文件路径，传入如 site/219/test/ 则是创建 test 文件夹
	 */
	public static void createFolder(String path) {
		FileUploadUtil.fileupload.createFolder(path);
	}
	
	public static UploadFileVO uploadFileVOTransfer(cn.zvo.fileupload.vo.UploadFileVO inputVO) {
		UploadFileVO vo = new UploadFileVO();
		BeanUtils.copyProperties(inputVO, vo);
		return vo;
	}
	
}
